/**
 * 本地存储工具类
 * 提供数据的本地存储、同步等功能
 */

import type { Event, EventType, DietType } from '@/types'

// 存储键名常量
const STORAGE_KEYS = {
  EVENTS: 'todo_calendar_events',
  EVENT_TYPES: 'todo_calendar_event_types',
  DIET_TYPES: 'todo_calendar_diet_types',
  SYNC_SETTINGS: 'todo_calendar_sync_settings',
  LAST_SYNC_TIME: 'todo_calendar_last_sync_time'
} as const

// 同步设置接口
export interface SyncSettings {
  autoSync: boolean
  syncInterval: number // 分钟
  lastSyncTime?: string
}

// 本地存储数据接口
export interface LocalStorageData {
  events: Event[]
  eventTypes: EventType[]
  dietTypes: DietType[]
  syncSettings: SyncSettings
  lastSyncTime?: string
}

/**
 * 本地存储管理类
 */
export class LocalStorageManager {
  
  /**
   * 保存事件数据到本地存储
   */
  static saveEvents(events: Event[]): void {
    try {
      localStorage.setItem(STORAGE_KEYS.EVENTS, JSON.stringify(events))
      this.updateLastSyncTime()
    } catch (error) {
      console.error('保存事件数据失败:', error)
      throw new Error('保存事件数据失败')
    }
  }

  /**
   * 从本地存储获取事件数据
   */
  static getEvents(): Event[] {
    try {
      const data = localStorage.getItem(STORAGE_KEYS.EVENTS)
      return data ? JSON.parse(data) : []
    } catch (error) {
      console.error('获取事件数据失败:', error)
      return []
    }
  }

  /**
   * 保存事件类型数据到本地存储
   */
  static saveEventTypes(eventTypes: EventType[]): void {
    try {
      localStorage.setItem(STORAGE_KEYS.EVENT_TYPES, JSON.stringify(eventTypes))
      this.updateLastSyncTime()
    } catch (error) {
      console.error('保存事件类型数据失败:', error)
      throw new Error('保存事件类型数据失败')
    }
  }

  /**
   * 从本地存储获取事件类型数据
   */
  static getEventTypes(): EventType[] {
    try {
      const data = localStorage.getItem(STORAGE_KEYS.EVENT_TYPES)
      return data ? JSON.parse(data) : []
    } catch (error) {
      console.error('获取事件类型数据失败:', error)
      return []
    }
  }

  /**
   * 保存饮食类型数据到本地存储
   */
  static saveDietTypes(dietTypes: DietType[]): void {
    try {
      localStorage.setItem(STORAGE_KEYS.DIET_TYPES, JSON.stringify(dietTypes))
      this.updateLastSyncTime()
    } catch (error) {
      console.error('保存饮食类型数据失败:', error)
      throw new Error('保存饮食类型数据失败')
    }
  }

  /**
   * 从本地存储获取饮食类型数据
   */
  static getDietTypes(): DietType[] {
    try {
      const data = localStorage.getItem(STORAGE_KEYS.DIET_TYPES)
      return data ? JSON.parse(data) : []
    } catch (error) {
      console.error('获取饮食类型数据失败:', error)
      return []
    }
  }

  /**
   * 保存同步设置
   */
  static saveSyncSettings(settings: SyncSettings): void {
    try {
      localStorage.setItem(STORAGE_KEYS.SYNC_SETTINGS, JSON.stringify(settings))
    } catch (error) {
      console.error('保存同步设置失败:', error)
      throw new Error('保存同步设置失败')
    }
  }

  /**
   * 获取同步设置
   */
  static getSyncSettings(): SyncSettings {
    try {
      const data = localStorage.getItem(STORAGE_KEYS.SYNC_SETTINGS)
      return data ? JSON.parse(data) : {
        autoSync: false,
        syncInterval: 30 // 默认30分钟
      }
    } catch (error) {
      console.error('获取同步设置失败:', error)
      return {
        autoSync: false,
        syncInterval: 30
      }
    }
  }

  /**
   * 更新最后同步时间
   */
  static updateLastSyncTime(): void {
    try {
      const now = new Date().toISOString()
      localStorage.setItem(STORAGE_KEYS.LAST_SYNC_TIME, now)
    } catch (error) {
      console.error('更新同步时间失败:', error)
    }
  }

  /**
   * 获取最后同步时间
   */
  static getLastSyncTime(): string | null {
    try {
      return localStorage.getItem(STORAGE_KEYS.LAST_SYNC_TIME)
    } catch (error) {
      console.error('获取同步时间失败:', error)
      return null
    }
  }

  /**
   * 保存所有数据到本地存储
   */
  static saveAllData(data: Partial<LocalStorageData>): void {
    try {
      if (data.events) this.saveEvents(data.events)
      if (data.eventTypes) this.saveEventTypes(data.eventTypes)
      if (data.dietTypes) this.saveDietTypes(data.dietTypes)
      if (data.syncSettings) this.saveSyncSettings(data.syncSettings)
    } catch (error) {
      console.error('保存所有数据失败:', error)
      throw new Error('保存数据失败')
    }
  }

  /**
   * 获取所有本地存储数据
   */
  static getAllData(): LocalStorageData {
    return {
      events: this.getEvents(),
      eventTypes: this.getEventTypes(),
      dietTypes: this.getDietTypes(),
      syncSettings: this.getSyncSettings(),
      lastSyncTime: this.getLastSyncTime() || undefined
    }
  }

  /**
   * 清除所有本地数据
   */
  static clearAllData(): void {
    try {
      Object.values(STORAGE_KEYS).forEach(key => {
        localStorage.removeItem(key)
      })
    } catch (error) {
      console.error('清除本地数据失败:', error)
      throw new Error('清除数据失败')
    }
  }

  /**
   * 获取本地存储使用情况
   */
  static getStorageInfo(): {
    used: number
    total: number
    percentage: number
    items: Record<string, number>
  } {
    try {
      const items: Record<string, number> = {}
      let totalUsed = 0

      Object.entries(STORAGE_KEYS).forEach(([name, key]) => {
        const data = localStorage.getItem(key)
        const size = data ? new Blob([data]).size : 0
        items[name] = size
        totalUsed += size
      })

      // 估算总可用空间（通常为5-10MB）
      const estimatedTotal = 5 * 1024 * 1024 // 5MB

      return {
        used: totalUsed,
        total: estimatedTotal,
        percentage: (totalUsed / estimatedTotal) * 100,
        items
      }
    } catch (error) {
      console.error('获取存储信息失败:', error)
      return {
        used: 0,
        total: 0,
        percentage: 0,
        items: {}
      }
    }
  }

  /**
   * 检查本地存储是否可用
   */
  static isStorageAvailable(): boolean {
    try {
      const testKey = '__storage_test__'
      localStorage.setItem(testKey, 'test')
      localStorage.removeItem(testKey)
      return true
    } catch {
      return false
    }
  }

  /**
   * 导出数据为JSON文件
   */
  static exportData(): string {
    const data = this.getAllData()
    return JSON.stringify(data, null, 2)
  }

  /**
   * 从JSON数据导入
   */
  static importData(jsonData: string): void {
    try {
      const data = JSON.parse(jsonData) as LocalStorageData
      this.saveAllData(data)
    } catch (error) {
      console.error('导入数据失败:', error)
      throw new Error('导入数据失败，请检查数据格式')
    }
  }
}

/**
 * 格式化存储大小
 */
export function formatStorageSize(bytes: number): string {
  if (bytes === 0) return '0 B'
  
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}
